package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.PutObjectResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nineclock.common.constant.MessageConstant;
import com.nineclock.common.constant.NcConstant;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.oss.OssProperties;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.message.pojo.NcMessage;
import com.nineclock.model.dto.*;
import com.nineclock.model.pojo.*;
import com.nineclock.system.mapper.*;
import com.nineclock.system.service.SysCompanyService;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SysCompanyServiceImpl implements SysCompanyService {

    @Autowired
    SysCompanyMapper sysCompanyMapper;

    @Autowired
    SysCompanyUserMapper sysCompanyUserMapper;

    @Autowired
    RedisTemplate<String,String> redisTemplate;

    /**
     * 根据系统用户id查询 ,企业列表
     * @param userId
     * @return
     */
    @Override
    public List<SysCompanyDTO> queryCompanyListByUserId(Long userId) {
        if (userId == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //根据 系统用户id 查询 企业员工列表
        LambdaQueryWrapper<SysCompanyUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysCompanyUser::getUserId,userId);
        //获取企业员工列表
        List<SysCompanyUser> companyUserList = sysCompanyUserMapper.selectList(queryWrapper);

        if (CollectionUtil.isEmpty(companyUserList)) {
            throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
        }

        //从企业员工列表中获取 企业id
        //map 可以把集合转换为一个新的集合
        //collect(Collectors.toSet()) 指定要转换成什么集合类型
        Set<Long> companyIds = companyUserList.stream().map(sysCompanyUser -> {
            return sysCompanyUser.getCompanyId();
        }).collect(Collectors.toSet());

        //再根据企业id获取 企业列表信息
        LambdaQueryWrapper<SysCompany> companyQw = new LambdaQueryWrapper<>();
        companyQw.in(SysCompany::getId,companyIds);

        List<SysCompany> companyList = sysCompanyMapper.selectList(companyQw);

        //转换为DTO
        List<SysCompanyDTO> companyDTOList = BeanHelper.copyWithCollection(companyList, SysCompanyDTO.class);

        return companyDTOList;
    }

    @Override
    public SysCompanyDTO queryCompanyInfo() {

        Long companyId = CurrentUserHolder.get().getCompanyId();

        SysCompany sysCompany = sysCompanyMapper.selectById(companyId);

        if (sysCompany==null) {
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }

        return BeanHelper.copyProperties(sysCompany, SysCompanyDTO.class);


    }

    @Autowired
    OSS ossClient;
    @Autowired
    OssProperties ossProperties;

    @Override
    public String uploadCompanyLogo(MultipartFile file) {

        if (file==null) {
            throw new NcException(ResponseEnum.FILE_NOT_FOUND);
        }

        String contentType = file.getContentType();
        //是否是图片
        if (!NcConstant.ALLOWED_IMG_TYPES.contains(contentType)) {
            throw new NcException(ResponseEnum.INVALID_FILE_TYPE);
        }
        if (file.getSize()>NcConstant.maxFileSize) {
            throw new NcException(ResponseEnum.FILE_SIZE_EXCEED_MAX_LIMIT);
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String fileName = format.format(new Date()) + file.getOriginalFilename();
        try {
            PutObjectResult objectResult = ossClient.putObject(ossProperties.getBucketName(), fileName, file.getInputStream());
            log.info("文件 {} 上传成功, 上传的结果为:{} ", fileName, objectResult.getResponse());
        } catch (IOException e) {
            e.printStackTrace();
            throw new NcException(ResponseEnum.FILE_UPLOAD_ERROR);
        }

        String imgUrl = String.format(ossProperties.getHost(), ossProperties.getBucketName()) + fileName;

        return imgUrl;

    }

    @Override
    public void updateCompanyInfo(SysCompanyDTO sysCompanyDTO) {
        if (sysCompanyDTO==null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        Long companyId = CurrentUserHolder.get().getCompanyId();

        //更新企业信息
        SysCompany sysCompany = BeanHelper.copyProperties(sysCompanyDTO, SysCompany.class);
        sysCompany.setId(companyId);
        sysCompanyMapper.updateById(sysCompany);

        //更新企业员工基本信息
        SysCompanyUser sysCompanyUser = new SysCompanyUser();
        sysCompanyUser.setCompanyName(sysCompanyDTO.getName());

        LambdaQueryWrapper<SysCompanyUser> updateWrapper = new LambdaQueryWrapper<>();
        updateWrapper.eq(SysCompanyUser::getCompanyId,companyId);
        sysCompanyUserMapper.update(sysCompanyUser,updateWrapper);

    }

    @Override
    public SysCompanyUserDTO getCurrentAdmin() {
        Long companyId = CurrentUserHolder.get().getCompanyId();

        SysCompanyUser sysCompanyUser = sysCompanyUserMapper.queryMainAdminCompanyUser(companyId);

        if (sysCompanyUser==null) {
            throw new NcException(ResponseEnum.COMPANY_ADMIN_NOT_EXISTS);
        }

        SysCompanyUserDTO sysCompanyUserDTO = BeanHelper.copyProperties(sysCompanyUser, SysCompanyUserDTO.class);

        return sysCompanyUserDTO;

    }
    @Autowired
    SysRoleMapper sysRoleMapper;

    @Autowired
    SysCompanyUserRoleMapper sysCompanyUserRoleMapper;

    @Override
    public void updateCompanyAdmin(SysChangeMainManagerDTO sysChangeMainManagerDTO) {
        if (sysChangeMainManagerDTO==null||StringUtils.isEmpty(sysChangeMainManagerDTO.getCode())||sysChangeMainManagerDTO.getUserId()==null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        Long companyId = CurrentUserHolder.get().getCompanyId();
        //新管理员是否存在
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getCompanyId, companyId);
        wrapper.eq(SysCompanyUser::getEnable, 1);
        wrapper.eq(SysCompanyUser::getId, sysChangeMainManagerDTO.getUserId());

        SysCompanyUser sysCompanyUser = sysCompanyUserMapper.selectOne(wrapper);
        if (sysCompanyUser==null) {
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }
        //验证码校验
        String realCode = redisTemplate.boundValueOps(SMSConstant.SMS_CHANGE_MANAGER_KEY_PREFIX + sysCompanyUser.getMobile()).get();

        if (realCode==null||!realCode.equals(sysChangeMainManagerDTO.getCode())) {
            throw new NcException(ResponseEnum.CODE_IMAGE_ERROR);
        }

        //删除老管理员权限
        LambdaQueryWrapper<SysRole> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(SysRole::getRoleName,"ROLE_ADMIN_SYS");
        wrapper1.eq(SysRole::getCompanyId,companyId);

        SysRole sysRole = sysRoleMapper.selectOne(wrapper1);

        LambdaQueryWrapper<SysCompanyUserRole> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(SysCompanyUserRole::getCompanyUserId, CurrentUserHolder.get().getCompanyUserId());
        wrapper2.eq(SysCompanyUserRole::getRoleId, sysRole.getId());
        wrapper2.eq(SysCompanyUserRole::getCompanyId,companyId);
        sysCompanyUserRoleMapper.delete(wrapper2);
        //给新管理员权限
        SysCompanyUserRole companyUserRole = new SysCompanyUserRole();
        companyUserRole.setCompanyId(companyId);
        companyUserRole.setRoleId(sysRole.getId());
        companyUserRole.setCompanyUserId(sysChangeMainManagerDTO.getUserId());

        sysCompanyUserRoleMapper.insert(companyUserRole);


    }

    //-------------------有问题--------------

    @Autowired
    SysRoleFunctionMapper sysRoleFunctionMapper;
    @Autowired
    SysFunctionMapper sysFunctionMapper;

    @Override
    public List<SysRoleDTO> permissions() {
        Long companyId = CurrentUserHolder.get().getCompanyId();
        LambdaQueryWrapper<SysRole> sysRoleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysRoleLambdaQueryWrapper.eq(SysRole::getCompanyId, companyId);
        List<SysRole> sysRoleList = sysRoleMapper.selectList(sysRoleLambdaQueryWrapper);
        ArrayList<SysFunction> sysFunctions = new ArrayList<>();
        ArrayList<SysRoleDTO> sysRoleDTOS = new ArrayList<>();
        for (SysRole sysRole : sysRoleList) {
            LambdaQueryWrapper<SysRoleFunction> sysRoleFunctionQw = new LambdaQueryWrapper<>();
            sysRoleFunctionQw.eq(SysRoleFunction::getRoleId,sysRole.getId());
            List<SysRoleFunction> sysRoleFunctions = sysRoleFunctionMapper.selectList(sysRoleFunctionQw);

            for (SysRoleFunction sysRoleFunction : sysRoleFunctions) {
                LambdaQueryWrapper<SysFunction> sysFunctionLambdaQueryWrapper = new LambdaQueryWrapper<>();
                sysFunctionLambdaQueryWrapper.eq(SysFunction::getCompanyId,companyId);
                sysFunctionLambdaQueryWrapper.eq(SysFunction::getId,sysRoleFunction.getFunctionId());
                SysFunction sysFunction = sysFunctionMapper.selectOne(sysFunctionLambdaQueryWrapper);
                sysFunctions.add(sysFunction);

            }
            List<SysFunctionDTO> sysFunctionDTOS = BeanHelper.copyWithCollection(sysFunctions, SysFunctionDTO.class);
            SysRoleDTO sysRoleDTO = new SysRoleDTO();
            sysRoleDTO.setId(sysRole.getId());
            sysRoleDTO.setRoleDesc(sysRole.getRoleDesc());
            sysRoleDTO.setRoleName(sysRoleDTO.getRoleName());
            sysRoleDTO.setCompanyId(companyId);
            sysRoleDTO.setSysFunctionAbbrList(sysFunctionDTOS);

            sysRoleDTOS.add(sysRoleDTO);
        }

        return sysRoleDTOS;
    }

    @Override
    public PageResult pageRole(Integer page, Integer pageSize) {
        if (page==null||pageSize==null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        Long companyId = CurrentUserHolder.get().getCompanyId();
        LambdaQueryWrapper<SysRole> sysRoleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysRoleLambdaQueryWrapper.eq(SysRole::getCompanyId, companyId);
        List<SysRole> sysRoleList = sysRoleMapper.selectList(sysRoleLambdaQueryWrapper);

        Integer total =0;

        PageResult<SysRole> result = new PageResult<>();

        for (SysRole sysRole : sysRoleList) {
            total+=1;
        }
        int i = total / pageSize;
        result.setTotalPage(Long.valueOf(i));
        result.setTotal(Long.valueOf(total));
        result.setRows(sysRoleList);

        return result;
    }


    //--------------------------------------

    @Override
    public List<SysCompanyDTO> queryCompanyByName(String keyword) {

        if (keyword==null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        LambdaQueryWrapper<SysCompany> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(SysCompany::getName,keyword);
        queryWrapper.eq(SysCompany::getAuditStatus,1);
        List<SysCompany> sysCompanies = sysCompanyMapper.selectList(queryWrapper);
        if (sysCompanies!=null) {
            return BeanHelper.copyWithCollection(sysCompanies,SysCompanyDTO.class);
        }

        return null;
    }
    @Autowired
    SysUserMapper sysUserMapper;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public void applyJoinCompany(SysApplyJoinCompanyUserDTO sysApplyJoinCompanyUserDTO) {

        if (sysApplyJoinCompanyUserDTO==null||sysApplyJoinCompanyUserDTO.getUserId()==null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        SysUser sysUser = sysUserMapper.selectById(sysApplyJoinCompanyUserDTO.getUserId());
        sysUser.setUsername(sysApplyJoinCompanyUserDTO.getUserName());
        sysUser.setEmail(sysApplyJoinCompanyUserDTO.getEmail());

        //注册就放一个值,要不没办法登录
        sysUser.setLastLoginCompanyId((long) 1);
        sysUserMapper.updateById(sysUser);

        SysCompanyUser sysCompanyUser = new SysCompanyUser();
        sysCompanyUser.setUserId(sysApplyJoinCompanyUserDTO.getUserId());
        sysCompanyUser.setCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId());
        sysCompanyUser.setCompanyName(sysApplyJoinCompanyUserDTO.getCompanyName());
        sysCompanyUser.setPost(sysApplyJoinCompanyUserDTO.getPost());
        sysCompanyUser.setEmail(sysApplyJoinCompanyUserDTO.getEmail());
        sysCompanyUser.setTimeEntry(new Date());
        sysCompanyUser.setRemark(sysApplyJoinCompanyUserDTO.getApplyReason());
        sysCompanyUser.setEnable((short) 0);
        sysCompanyUser.setCreateTime(new Date());
        sysCompanyUser.setUpdateTime(new Date());
        sysCompanyUser.setMobile(sysApplyJoinCompanyUserDTO.getMobile());
        sysCompanyUser.setUserName(sysApplyJoinCompanyUserDTO.getUserName());
        sysCompanyUser.setRemark(sysApplyJoinCompanyUserDTO.getApplyReason());
        log.info("保存企业员工信息 ");
        sysCompanyUserMapper.insert(sysCompanyUser);

        SysCompanyUser companyUser = sysCompanyUserMapper.queryMainAdminCompanyUser(sysApplyJoinCompanyUserDTO.getCompanyId());
        if (companyUser!=null) {
            NcMessage message = new NcMessage();
            message.setApplyUserId(sysApplyJoinCompanyUserDTO.getUserId());//申请人id
            message.setApplyUsername(sysApplyJoinCompanyUserDTO.getUserName());
            message.setMessageType(MessageConstant.COMPANY_APPLY);
            message.setContent(sysApplyJoinCompanyUserDTO.getUserName()+" 申请加入企业,请及时审批!");
            message.setApproveUserId(companyUser.getUserId());//管理员id
            message.setApproveUsername(companyUser.getUserName());
            message.setTargets(Collections.singletonList(companyUser.getMobile()));

            log.info("发送消息到MQ, 推送审批消息给系统管理员 ");
            rocketMQTemplate.convertAndSend("messagePushTopic", message);
        }


    }


}
